#!/bin/bash

set -eux

DEV=dev
DIR=dir
SIZE=1G
MODE=normal
OPTS='-o default_permissions,allow_other,big_writes,attr_timeout=0'

usage()
{
    cat <<HERE
Usage: $0 [options]
Options:
  -d DIR    Create if necessary and mount inside DIR. (default: $DIR)
  -f DEV    Name of the device to create, mkfs and mount. (default: $DEV).
  -g        Run gdb when mounting.
  -o OPTS   Pass OPTS to the mount command. (default: $OPTS)
  -s SIZE   Truncate DEV to SIZE. (default: $SIZE)
  -v        Run valgrind when mounting.

This script is part of cpfs
HERE
}

trap usage EXIT
# see the following link for how and why getopt is done this way
# http://software.frodo.looijaard.name/getopt/docs/getopt-parse.bash
args=$(getopt -o d:f:go:s:v -- "$@")
eval set -- "$args"
while [ $# -ne 0 ]
do
    case "$1" in
        -d) DIR=$2; shift 2;;
        -f) DEV=$2; shift 2;;
        -g) MODE=gdb; shift;;
        -o) OPTS=$2; shift 2;;
        -s) SIZE=$2; shift 2;;
        -v) MODE=valgrind; shift;;
        --) shift; break;;
        *) echo "Error parsing arguments"; exit 2;;
    esac
done
[ $# -eq 0 ] || exit 2

mounted=''

cleanup()
{
    set +e
    false
    if [ -n "$mounted" ]; then
        sudo fusermount -uz "$DIR"
    fi
    sudo losetup -d "$loop"
    set -e
}

trap cleanup EXIT

truncate -s "$SIZE" "$DEV"
loop="$(sudo losetup --show -f "$DEV")"
if [ "$MODE" = gdb ]; then
    sudo LD_LIBRARY_PATH=`pwd` gdb -return-child-result -x gdbbatch --args ./mkfs.cpfs "$loop"
else
    sudo LD_LIBRARY_PATH=`pwd` ./mkfs.cpfs "$loop"
fi
echo mkfs.cpfs exited with status $?.
[ -d "$DIR" ] || mkdir "$DIR"
mounted=t
# http://stackoverflow.com/questions/3665533/quoting-in-a-bash-variable-assignment
mount_command=(./mount.cpfs "$loop" "$DIR" -f $OPTS)
case "$MODE" in
    gdb)
        sudo LD_LIBRARY_PATH=`pwd` gdb -return-child-result -x gdbbatch \
            --args "${mount_command[@]}"
        ;;
    normal)
        time sudo CPUPROFILE=mount.cpfs.gglprof LD_LIBRARY_PATH=`pwd` "${mount_command[@]}"
        ;;
    valgrind)
        sudo LD_LIBRARY_PATH=`pwd` valgrind --track-fds=yes --leak-check=full \
            --malloc-fill=0x80 --free-fill=0xff "${mount_command[@]}"
        ;;
    *)
        echo "Mode '$MODE' unknown"
        mounted=''
        exit 2
        ;;
esac
echo mount.cpfs exited with status $?.
mounted=''
